//
// Created by hsj on 2021/12/21.
//
#include <iostream>
#include "ref_cpp.h"
using namespace std;

void test_ref(){
    int a = 100;
    int &b = a;
    b = 200;
    std::cout<<a<<std::endl<<b<<std::endl;
    //打印地址[相同]
    //初始化一次，之后誓死效忠初始化的对象
    //引用，顾名思义是某一个变量或对象的别名（另一个名称），对引用的操作与对其所绑定的变量或对象的操作完全等价
    //&引用操作类比typedef换一个别名:
    //         typedef int it;

    //引用类比于const指针：
    //int a = 18;
    //int &b = a;
    //int * const c = &a;

    std::cout<<&a<<std::endl<<&b<<std::endl;//地址一样，只是两个不同的别名
    int primit = 199;
//    c++基本数据转指针类型（C语言也这么做）；
//    指针一般8字节，int大多数4字节或者有可能2字节。long long 8字节匹配指针。
    void *p = (void *)primit;
    std::cout<<p<<std::endl;
    long long primit_int = (long long)p;
    std::cout<<primit_int<<std::endl;
      int &primit_ref = primit;
      std::cout<<primit_ref<<std::endl;

      int c = 18;
      int d;
      d = valplus(c);
      std::cout<<c<<std::endl<<d<<std::endl;

      int &e = valplus_r(c);
      std::cout<<c<<std::endl<<e<<std::endl;

//    初始化一次，之后誓死效忠初始化的对象:c、e地址一样，d是新的变量地址。某次运行如下
//    0x89fdcc
//    0x89fdc8
//    0x89fdcc
      std::cout<<&c<<std::endl<<&d<<std::endl<<&e<<std::endl;


    //int a = 18; 表达式（a + 18）、强制类型转换（const修饰并且实参不匹配）、魔术值 传递给引用，将会导致引用指向该无名变量
    double side = 3.0;
    double *pd  = &side;
    double &rd = side;
    long endge = 5L;
    double lens[4]{2.0,3.0,4.0,5.0};

    double c1 = refcube(side);                     // OK,ra is side
    double c2 = refcube(lens[2]);               // OK,ra is lens[2]
    double c3 = refcube(rd);                       // OK,ra is rd is side
    double c4 = refcube(*pd);                      // OK,ra is *pd is side
    double c5 = refcube(endge);                    //ERROR,ra is temporary variable --call exsist调用时候存在的临时变量
    double c6 = refcube(7.0);                   //ERROR,ra is temporary variable --call exsist调用时候存在的临时变量
    double c7 = refcube(side + 1.0);            //ERROR,ra is temporary variable --call exsist调用时候存在的临时变量

    //C++11新增加右值引用（临时变量引用：temporary variable ref）
    double &&rref = side + 18.0;

}
void test_getchar_cmd(){
//    char ch;
//    std::cin.get(ch);
//    std::cout<<ch<<endl;
    int age;
    cin>>age;
    cout<<age<<endl;
}
int valplus(int &a){
    a = a + 2;
    return a;
}

int &valplus_r(int &a){
    a = a + 2;
    return a;
//    不要试图返回局部变量引用，栈使用完便销毁了
//    int aa = a + 2;
//    return aa;
}

//int a = 18; 表达式（a + 18）、强制类型转换（const修饰并且实参不匹配）、魔术值 传递给引用，将会导致引用指向该无名变量
double refcube(const double &ra){
    return ra * ra * ra;
}